package cn.iocoder.yudao.module.train.controller.wechat.login;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.train.controller.admin.student.vo.StudentSaveReqVO;
import cn.iocoder.yudao.module.train.controller.admin.wxuser.vo.WxUserRespVO;
import cn.iocoder.yudao.module.train.controller.admin.wxuser.vo.WxUserSaveReqVO;
import cn.iocoder.yudao.module.train.controller.wechat.login.config.WeChatConstants;
import cn.iocoder.yudao.module.train.controller.wechat.login.jwt.service.IWxMiniJwtService;
import cn.iocoder.yudao.module.train.controller.wechat.login.vo.WxUsersLoginRespVO;
import cn.iocoder.yudao.module.train.dal.dataobject.WxUser.WxUserDO;
import cn.iocoder.yudao.module.train.dal.dataobject.connectDTO.StudentUserDTO;
import cn.iocoder.yudao.module.train.dal.mysql.WxUser.WxUserMapper;
import cn.iocoder.yudao.module.train.service.student.StudentService;
import cn.iocoder.yudao.module.train.service.wxUser.WxUserService;
import com.alibaba.fastjson2.JSON;
import com.fhs.core.trans.anno.TransMethodResult;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.train.enums.ErrorCodeConstants.WX_USER_NOT_EXISTS;

@Tag(name = "小程序接口 - 登录")
@RestController
@RequestMapping("/wechat-api/login")
@Validated
public class LoginController {

    @Autowired
    private WxUserMapper wxUsersMapper;

    @Resource
    private IWxMiniJwtService jwtService;

    @Resource
    private WxUserService wxUserService;

    @Resource
    private StudentService studentService;

    private static String generateName() {
        //生成“用户+六位英文”
        return "用户" + generateRandomString(6);
    }

    private static String generateRandomString(int i) {
        StringBuilder sb = new StringBuilder();
        for (int j = 0; j < i; j++) {
            sb.append((char) (Math.random() * 26 + 'a'));
        }
        return sb.toString();
    }

    /**
     * 生成token
     */
    @PostMapping("/wxToken")
    public CommonResult<String> wxToken(Long userId) {
        return success(jwtService.createToken(String.valueOf(userId)));
    }

    /**
     * 微信登录
     *
     * @param params
     * @return
     */
    @PostMapping("/wxLogin")
    @TransMethodResult
    public CommonResult<WxUsersLoginRespVO> wxLogin(@RequestBody Map<String, Object> params) {
        try {
            String code = MapUtils.getString(params, "code"); //临时登陆凭证
            Map<String, String> param = new HashMap<>();
            param.put("appid", WeChatConstants.APPID);
            param.put("secret", WeChatConstants.SECRET);
            param.put("grant_type", "authorization_code");
            param.put("js_code", code);

            //解析出的登陆凭证（json字符串）
            String res = HttpUtils.get("https://api.weixin.qq.com/sns/jscode2session", null, param);
            Map<String, Object> resultMap = Maps.newHashMap();
            String openId = null;
            if (res != null) {
                resultMap = JSON.parseObject(res, Map.class);
                openId = MapUtils.getString(resultMap, "openid"); //尝试解析openid
            }

            //登陆出错
            if (openId == null) {
                Integer errcode = MapUtils.getInteger(resultMap, "errcode");
                String errmsg = MapUtils.getString(resultMap, "errmsg");
                return error(errcode, errmsg);
            } else {
                if (wxUsersMapper.selectOne(WxUserDO::getUOpenId, openId) == null) { //数据库中openid不存在创建新用户
                    WxUserDO trWxUser = new WxUserDO();
                    trWxUser.setUOpenId(openId);
                    trWxUser.setUName(generateName());
                    wxUsersMapper.insert(trWxUser);
                    trWxUser.setUAvatar("https://picsum.photos/seed/" + trWxUser.getId() + "/200/200");
                    wxUsersMapper.updateById(trWxUser);
                }
                //老用户
                WxUserDO trWxUser = wxUsersMapper.selectOne(WxUserDO::getUOpenId, openId);
                WxUsersLoginRespVO wxUsersLoginResVO = BeanUtils.toBean(trWxUser, WxUsersLoginRespVO.class);
                wxUsersLoginResVO.setApiToken(jwtService.createToken(String.valueOf(trWxUser.getId())));

                return success(wxUsersLoginResVO);
            }
        } catch (Exception e) {
            return error(500, e.getMessage());
        }
    }

    /**
     * 更新用户信息
     */
    @PostMapping("/updateUserInfo")
    @Operation(summary = "更新用户信息")
    public CommonResult<WxUserRespVO> updateUserInfo(@RequestBody WxUserSaveReqVO trWxUser) {
        try {
            String openId = trWxUser.getUOpenid();
            String nickName = trWxUser.getUName();
            String avatarUrl = trWxUser.getUAvatar();
            String uPhoneNumber = trWxUser.getUPhoneNumber();
            // 手动非空判断
            if (openId == null || openId.trim().isEmpty()) {
                return error(1000_0_3,"openId不能为空");
            }
            if (nickName == null || nickName.trim().isEmpty()) {
                return error(1000_0_12,"nickName不能为空");
            }
            if (uPhoneNumber == null || uPhoneNumber.trim().isEmpty()) {
                return error(1000_0_13,"uPhoneNumber不能为空");
            }
            WxUserDO user = wxUserService.getWxUserByOpenId(openId);
            if (user == null) {
                return error(WX_USER_NOT_EXISTS);
            }
            user.setUName(nickName);
            user.setUAvatar(avatarUrl);
            user.setUPhoneNumber(uPhoneNumber);
            StudentUserDTO student = studentService.getStudentByPhoneNumber(uPhoneNumber);
            if (student != null) {
                student.setUserId(user.getId());
                studentService.updateStudent(BeanUtils.toBean(student, StudentSaveReqVO.class));
            }
            user.setCreator("wxUser"+user.getUOpenId());
            wxUserService.updateWxUser(user);
            return success(BeanUtils.toBean(user,WxUserRespVO.class));
        } catch (Exception e) {
            return error(1000_0_11,e.getMessage());
        }
    }
}
